// app/service/news.js
const Service = require('egg').Service;
var http = require('http');
var cheerio = require('cheerio');
var iconv = require('iconv-lite');
let fs = require('fs');
var moment = require('moment');

/**
 * 招聘目标页的配置对象
 */
const websiteConfig = {
  cxjy: {
    name: '岑溪家园网',
    url: 'http://www.077455.com/forum-50-1.html',
    abbr: 'CXJY',
    prefix: 'http://www.077455.com/'
  },
  cxrj: {
    name: '岑溪人家论坛',
    url: 'http://www.8220365.com/forum.php?mod=forumdisplay&fid=96',
    abbr: 'CXRJ',
    prefix: 'http://www.8220365.com/'
  },
  wztc: {
    name: '梧州同城招聘',
    url: '',
    abbr: 'WZTC',
    prefix: ''
  }
}

class SpiderService extends Service {

  // 加载页面
  huntPage(url) {
    return new Promise((resolve, reject) => {
      http.get(url, function (sres) {
        var chunks = [];
        sres.on('data', function (chunk) {
          chunks.push(chunk);
        });
        sres.on('end', function () {
          resolve(chunks);
        });
      });
    });
  }

  // 根据编码格式转译页面成cheerio对象
  translate(chunks) {
    return new Promise((resolve, reject) => {

      try {
        var html = iconv.decode(Buffer.concat(chunks), 'gbk');
        var $ = cheerio.load(html, {
          decodeEntities: false
        });
        resolve($);
      } catch (error) {
        reject(error);
      }

    });
  }

  async huntLocalPage() {
    let config = websiteConfig.wztc;
    console.log('huntLocalPage', config);

    // 载入本地页面
    let $ = cheerio.load(fs.readFileSync('../crqs_server/local_file/梧州同城招聘网.html'), {
      decodeEntities: false
    });

    // 获取标题栏包含岑溪的section标签
    let $targetDomList = $('#js_content').find('section[style="white-space: normal;font-size: 14px;text-align: center;"] :contains(岑溪)');

    await $targetDomList.each(async (i, el) => {

      // 标题section相邻的就是内容section
      let $context = $(el).parent().next();

      //获取标题并移除DOM
      let jobTitle = $($context.children().children('p')[0]).text().trim().replace(/\*/g, '');
      $($context.children().children('p')[0]).remove();

      // 删除版权、日期和说明
      $context.children().find('p').last().remove();
      $context.children().find('p').last().remove();
      $context.children().find('p').last().remove();

      // 去除样式和粗字体的标签
      $context.find('*').removeAttr('style');
      // if(i == 0){
      //   console.log($context.html());
      // }
      let jobText = $.html($context.children())
        .replace(/<strong/g, '<span')
        .replace(/<\/strong/g, '</span');

      // 判断，招聘信息是否已存在
      let isExist = await this.contentIsExist(jobText);
      console.log($context.text().length, isExist);

      if ($context.text().length > 2 && !isExist) {

        let jobData = {
          // 系统ID：招聘来源+录入时间+序号
          oid: config.abbr + '_' + new Date().getTime() + i,
          // 招聘类型
          type: 'SPIDER',
          // 招聘状态
          status: 'INIT',
          // 招聘标题
          title: jobTitle,
          // 招聘明细链接
          link: null,
          // 招聘明细
          text: jobText,
          // 招聘作者
          author: config.name,
          // 招聘明细DOM
          detail_dom: null,
          // 招聘创建时间
          createTime: new Date(),
          // 招聘记录时间
          recordTime: new Date(),
          // 招聘发布时间：维持1天
          cutoffTime: new Date(new Date().getTime() + 86400000),
          // 留言
          comment_list: [],
          // 星选招聘
          star: false
        };
        console.log('local',jobData);
        this.insert(jobData);
      }
    })
  }

  // 爬虫入库 
  async index(param) {

    try {
      var target = param;
      var config = websiteConfig[target] ? websiteConfig[target] : websiteConfig.cxrj;
      // console.log('index service',target);
      if (target !== 'wztc') {
        // 根据URL，读取招聘列表页
        this.huntPage(config.url).then(async (chunks) => {
          // 页面转译
          this.translate(chunks).then(async ($) => {

            // 1. 获取招聘列表的cheerio对象
            let $domList = $('table#threadlisttableid').find('tbody');
            await $domList.each(async (idx, element) => {
              let $jobLinkDom = $(element);
              // 忽略网站顶置的招聘信息，只抓取普通的招聘信息
              if ($jobLinkDom.attr('id').indexOf('normalthread_') != -1) {
                // 2. 解析招聘列表
                let $link = $jobLinkDom.find('th.new a.s.xst');
                let createTime = $jobLinkDom.find('td.by em span span').attr('title');
                let $opreation = $jobLinkDom.find('th.new a.showcontent.y');

                let jobId = config.abbr + '_' + $opreation.attr('id').replace(/content_/, '');
                let jobDetailLink = config.prefix + $link.attr('href');
                let jobTitle = $link.text();


                let jobData = {
                  // 系统ID
                  oid: jobId,
                  // 招聘类型
                  type: 'SPIDER',
                  // 招聘状态
                  status: 'INIT',
                  // 招聘标题
                  title: jobTitle,
                  // 招聘明细链接
                  link: jobDetailLink,
                  // 招聘明细
                  text: null,
                  // 招聘作者
                  author: config.name,
                  // 招聘明细DOM
                  detail_dom: null,
                  // 招聘创建时间
                  createTime: createTime ? new Date(createTime) : new Date(),
                  // 招聘记录时间
                  recordTime: new Date(),
                  // 招聘发布时间（站外招聘只挂一天）
                  cutoffTime: new Date(new Date().getTime() + 86400000),
                  // 留言
                  comment_list: [],
                  // 星选招聘
                  star: false
                };

                console.log('jobData', jobData);
                if (!await this.isExist(jobTitle)) {

                  // 根据URL，读取招聘详情页
                  this.huntPage(jobDetailLink).then(async (detailChunks) => {
                    // 页面转译
                    this.translate(detailChunks).then(async ($) => {

                      var $div = null;
                      let $infoList = [];
                      if (config.abbr === 'CXRJ') {
                        $infoList = $('div#ct div#postlist > div');
                        for (let index = 0; index < $infoList.length; index++) {
                          const element = $infoList[index];
                          if (index === 0) {
                            $div = $(element).find('table.plhin div.pct div.t_fsz table tbody tr td.t_f');
                          } else if (index != 0 && index != $infoList.length) {
                            let comment = $(element).find('table.plhin div.pct div.t_fsz table tbody tr td.t_f').text();
                            if (comment) {
                              jobData.comment_list.push(comment);
                            }
                          }
                        }
                      } else {
                        $infoList = $('div#ct div#postlist > div');
                        for (let index = 0; index < $infoList.length; index++) {
                          const element = $infoList[index];
                          if (index === 0) {
                            $div = $(element).find('table.plhin div.pct div.t_fsz table tbody tr td.t_f');
                          } else if (index != 0 && index != $infoList.length) {
                            let comment = $(element).find('table.plhin div.pct div.t_fsz table tbody tr td.t_f').text();
                            if (comment) {
                              jobData.comment_list.push(comment);
                            }
                          }
                        }
                      }

                      if ($div && $div.find) {
                        $div.find('div.a_pr').remove();
                        $div.find('div.attach_nopermission.attach_tips').remove();
                        $div.find('*').removeAttr('style');
                      }

                      try {
                        jobData.text = $.html($div);
                        if (jobData.text) {
                          jobData.text = jobData.text
                            .replace(/strong/g, 'span')
                            .replace(/font/g, 'span');
                        }
                      } catch (error) {
                        console.error(error)
                      }


                      await this.insert(jobData);
                    });
                  });
                }
              }
            });

            return true;
          }).catch(() => {
            return false;
          });
        }).catch((e) => {
          return false;
        });
      } else {
        // 固定路径读取文件，并转换成chunks
        this.huntLocalPage();
      }
    } catch (error) {
      console.error(error);
    }

  }

  // 查询招聘信息是否存在
  async isExist(title) {
    const ctx = this.ctx;

    let data = await ctx.model.Job.find({
      title: title
    });
    return data.length > 0 ? true : false;
  }

  // 判断电话是否存在
  async phoneIsExist(phone) {
    const ctx = this.ctx;

    let data = await ctx.model.Job.find({
      text: {
        '$regex': phone
      }
    });
    return data.length > 0 ? true : false;
  }


  // 判断内容是否存在
  async contentIsExist(text) {
    const ctx = this.ctx;

    let data = await ctx.model.Job.find({
      text: text
    });
    // console.log(data);
    return data.length > 0 ? true : false;
  }

  // 新建招聘
  async createJob(job) {
    console.log('createJob come in');
    // console.log(job);
    // const ctx = this.ctx;
    // return ctx.model.Job.save(job).then(res => {
    //   console.log(res)
    //   return {
    //     success: true,
    //     msg: res,
    //     code: 0
    //   }
    // })
    return this.insert(job);
  }


  // 新增招聘信息
  async insert(jobData) {
    const ctx = this.ctx;
    console.log('insert', jobData)
    ctx.model.Job.update({
      text: jobData.text,
      oid: jobData.oid
    }, jobData, {
      upsert: true
    }).then(res => {
      console.log(res)
      return {
        success: true,
        msg: res,
        code: 0
      }
    }).catch(err => {
      console.log(err)
      return {
        success: false,
        err: err
      }
    })
  }


  // 查询未发布的招聘信息
  async show() {
    const ctx = this.ctx;

    let searchDate = ctx.query.searchDate;
    let starFlag = ctx.queries.star == 'true';
    let type = ctx.queries.type;
    let status = ctx.queries.status;

    let queryParam = {};
    let govList = [];
    let orgList = [];
    let spiderList = [];

    // 查询在指定时间之后cutoff的招聘信息
    if (searchDate) {
      queryParam = Object.assign(queryParam, {
        cutoffTime: {
          '$gte': new Date(parseInt(searchDate))
        }
      });
    }

    try {

      // 是否查询星选招聘
      if (starFlag) {

        // 查询公职招聘
        let govParam = Object.assign(queryParam, {
          type: {
            '$in': 'GOVERNMENT'
          },
        });
        govList = await ctx.model.Job.find(govParam);

        // 查询星标的原创招聘
        let orgParam = Object.assign(queryParam, {
          type: {
            '$in': 'ORIGINAL',
            star: true,
          }
        });
        orgList = await ctx.model.Job.find(orgParam);

        // 查询星标的站外招聘
        let spiderParam = Object.assign(queryParam, {
          type: {
            '$in': 'SPIDER',
            star: true,
          }
        });
        spiderList = await ctx.model.Job.find(spiderParam);

      } else {

        // 查询指定状态下的招聘信息
        if (status) {
          queryParam = Object.assign(queryParam, {
            status: {
              '$in': status
            }
          });
        }

        // 查询公职招聘
        let govParam = Object.assign(queryParam,{
          type: 'GOVERNMENT',
          cutoffTime: {
            '$gte': new Date(parseInt(searchDate))
          }
        });
        console.log('【公职招聘】', govParam);
        govList = await ctx.model.Job.find(govParam);

        // 查询原创招聘
        let orgParam =  Object.assign(queryParam, {
          type: 'ORIGINAL',
          cutoffTime: {
            '$gte': new Date(parseInt(searchDate))
          }
        });
        console.log('【orgParam】', orgParam);
        orgList = await ctx.model.Job.find(orgParam);
        // console.log('【orgList】',orgList.length);

        // 查询站外招聘
        let spiderParam = Object.assign(queryParam, {
          type: {
            '$in': 'SPIDER'
          }
        });
        spiderList = await ctx.model.Job.find(spiderParam);
      }
    } catch (error) {
      console.error(error);
    }


    return {
      govList,
      orgList,
      spiderList
    };
  }

  // 根据oid查询招聘信息
  async showJobByOid(oid) {
    const ctx = this.ctx
    return await ctx.model.Job.find({
      oid: oid
    })
  }

  // 批量标识成发布
  async publish() {
    const ctx = this.ctx
    return ctx.model.Job.update({
      status: ['CONFIRM', 'INIT'],
      publishTime: null
    }, {
      $set: {
        status: 'PUBLISH',
        publishTime: new Date()
      }
    }, {
      multi: true,
      upsert: false
    })
      .then(res => {
        return {
          success: true,
          msg: res,
          code: 0
        }
      }).catch(err => {
        return {
          success: false,
          err: err
        }
      })
  }

  async screenShot() {
    return new Promise((resolve, reject) => {
      // setTimeout(function() {
      //   resolve(true);
      // }, 1000);

      // var phantom = require('phantom');
      // phantom.create((error, ph) => {
      //   ph.createPage((err, page) => {
      //     page.viewportSize = {width: 470, height: 100};
      //     page.open('http://localhost:8080/#/', function () {
      //       // setTimeout(function () {
      //       let fileName = moment(new Date().getTime()).format('yyyy-MM-dd') + '.png';
      //       console.log(fileName);
      //       page.render('D:/test.png', () => {
      //         console.log("page rendered");
      //         phantom.exit();
      //       });
      //       // }, 200);
      //     });
      //   })
      // })



    });
  }

  async save(jobData) {
    const ctx = this.ctx;
    return ctx.model.Job.update({
      oid: jobData.oid
    }, {
      $set: {
        comment_list: jobData.comment_list,
        cutoffTime: jobData.cutoffTime,
        status: jobData.status,
        text: jobData.text,
        title: jobData.title
      }
    })
      .then(res => {
        return {
          success: true,
          msg: res,
          code: 0
        }
      }).catch(err => {
        return {
          success: false,
          err: err
        }
      })
  }


  async star(paramData) {
    const ctx = this.ctx;
    return ctx.model.Job.update({
      oid: paramData.oid
    }, {
      $set: {
        star: paramData.flag
      }
    })
      .then(res => {
        return {
          success: true,
          msg: res,
          code: 0
        }
      }).catch(err => {
        return {
          success: false,
          err: err
        }
      })
  }

  // 状态修改
  async changeStatus(oids, status) {
    const ctx = this.ctx;
    return ctx.model.Job.update({
      oid: {
        $in: oids
      }
    }, {
      $set: {
        status: status
      }
    }, {
      "multi": true // update only one document 
    })
      .then(res => {
        return {
          success: true,
          msg: res,
          code: 0
        }
      }).catch(err => {
        return {
          success: false,
          err: err
        }
      })
  }
}

module.exports = SpiderService;